Skip to content

Stage 2: make_clean_run(description=...) builds a described run for tests - #228

Merged
guijacquemet merged 2 commits into
mainfrom
claude/clean-run-described
Nov 8, 2026
Merged

guijacquemet merged 2 commits into
mainfrom
claude/clean-run-described

Conversation

@guijacquemet

Copy link
Copy Markdown
Contributor

What

testing.make_clean_run(folder, description=...) builds a described run, so downstream bricks can test Stage 2.

  • description is a published experiment description: bytes or text (published unchanged, so the run records their SHA-256) or a Description (written canonically).
  • The helper writes the declared tree: image_count tiny images per member, with the unit's channels. An rgb unit is written as RGB colour (YXS).
  • mask_types are then IDs of the description's masks. It writes one mask per image for each ID (instances: two labelled squares; binary: one region of 1s).
  • It publishes the bytes as morphobricks.toml, runs preprocessing and, with masks, the mask step.
  • It returns the same CleanRun, with a new last field description (None for an undescribed run).
  • testing.make_described_run(folder, description, masks=..., mask_step=...) is the same with the mask step optional, so masks can be left not yet checked (P28 tests).
  • axes, shape, pixel_size, design and seed raise ValueError together with a description. They are replaced by the description, so nothing is silently ignored.
  • Without description, make_clean_run behaves as before, and its signature gains only the last keyword.
  • Contract §9.1 and the CHANGELOG are updated.
  • unit_folder moved from tests/description_tree.py into the new module testing_described.py, and the tests import it from there. The code rules refuse identical function bodies, so it could not stay in both.

Why

Stage 2 design, PR 1 (section 1.1, "testing.make_clean_run cannot build a described run"). Every brick's Stage 2 test needs one.

Regression evidence

New tests/test_make_described_run.py (21 tests). Each of v03 v08 v13 v28 v30 v33 v34 builds, opens with RunInputs, and fovs() gives the fixture's canonical IDs. The expected multiset of (condition ID, repeat group, technical repeat ID, channel IDs), with its image count, is computed from the parsed description. The file also covers the published bytes, v28 as RGB, v08 masks checked and unchecked, the refusals, and the unchanged undescribed behaviour.

On main the file fails at collection (make_described_run and the description argument do not exist), so 0 of 21 run. With the change, 21 pass.

Checks

python tools/check.py: ruff check and format clean, 4596 passed, 4 skipped, code rules clean. The 4 skips are environmental: 3 need a case-sensitive-name file system check (test_cli_log.py:165, test_folder_rules.py:201 and :229) and 1 needs file modes to apply (test_discovery.py:665, running as root). testing_described is declared an orchestration module in pyproject.toml.

Needs an owner decision

  • The design said description=<Spec fixture name or bytes>. Only bytes, text and Description are accepted, because the Spec fixtures are not part of the installed package. A brick passes the bytes of its own vendored fixture. A name lookup would need the package to find a Spec checkout: say so if you want it.
  • make_clean_run is at the 8-parameter limit, so the mask step is optional only in make_described_run. make_clean_run(description=..., mask_types=...) always runs it.
  • Heterogeneous fixtures (v17, v29) are not built. A description mixing rgb and fluorescence units raises ValueError, and preprocessing refuses partial channel presence (P04).
  • CHANGELOG and contract §9.1 conflicts with the other Stage 2 PRs, Z projection 5/6: the run side (part of #176) #217 and List images without header channel names in a described run #226 are expected. Keep both sides.

Generated by Claude Code

Stage 2 design PR 1. A brick's Stage 2 test needs a run with a published
experiment description. make_clean_run takes description (bytes, text or a
Description) and builds the declared tree (image_count images per member,
RGB colour for rgb units), the declared masks named in mask_types, publishes
the bytes, runs preprocessing and the mask step. make_described_run does the
same with the mask step optional. Without description, nothing changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Scma6W3LC11s3qjXHZuGDm
@guijacquemet
guijacquemet merged commit 8eb5b2f into main Nov 8, 2026
7 checks passed
@guijacquemet
guijacquemet deleted the claude/clean-run-described branch November 8, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants